package main

import (
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// 设备信息模型（保持不变）
type DeviceInfo struct {
	ID         string `json:"id" gorm:"primaryKey"`
	Brand      string `json:"brand"`
	Model      string `json:"model"`
	OS         string `json:"os"`
	OSVersion  string `json:"os_version"`
	MACAddress string `json:"mac_address" gorm:"unique"`
	CPU        string `json:"cpu"`
	RAM        string `json:"ram"`
	Storage    string `json:"storage"`
	ScreenSize string `json:"screen_size"`
	Resolution string `json:"resolution"`
	Battery    int    `json:"battery"`
	CreatedAt  string `json:"created_at"`
}

// 分页响应结构体（新增）
type PaginationResponse struct {
	Total    int64        `json:"total"`    // 总条数
	Page     int          `json:"page"`     // 当前页码
	PageSize int          `json:"pageSize"` // 每页条数
	Data     []DeviceInfo `json:"data"`     // 分页数据
}

// 统一响应结构体（更新）
type Response struct {
	Msg  string      `json:"msg"`
	Code int         `json:"code"`
	Data interface{} `json:"data"` // 可接收分页数据或单条数据
}

// 设备品牌、型号等常量（保持不变）
var brands = []string{"小米", "华为", "苹果", "三星", "OPPO", "vivo", "一加", "荣耀", "魅族", "Redmi"}

// 设备型号列表（按品牌分组）
var models = map[string][]string{
	"小米":    {"10 Pro", "11 Ultra", "12S Ultra", "Civi 3", "13 Pro", "Note 12 Pro", "Mix Fold 3"},
	"华为":    {"Mate 60 Pro", "P60 Pro", "Nova 11 Pro", "Mate X3", "Pocket S", "MateBook E", "畅享 60X"},
	"苹果":    {"iPhone 14 Pro Max", "iPhone 13", "iPhone SE", "iPad Pro", "MacBook Air", "Apple Watch Ultra", "AirPods Pro"},
	"三星":    {"Galaxy S23 Ultra", "Galaxy Z Fold5", "Galaxy Z Flip5", "Galaxy Tab S8", "Galaxy A54", "Galaxy Book3", "Galaxy S23"},
	"OPPO":  {"Find X7 Ultra", "Reno10 Pro+", "K11", "Ace 2 Pro", "Find N3 Flip", "A2 Pro", "Reno10"},
	"vivo":  {"X90 Pro+", "iQOO 11", "S17 Pro", "X Fold2", "Y78+", "iQOO Neo8", "X90"},
	"一加":    {"11", "Ace 2", "Nord N30", "10 Pro", "Ace Pro", "Nord CE 3 Lite", "11R"},
	"荣耀":    {"Magic5 Pro", "荣耀 90", "X50", "Magic Vs", "Play 7T", "MagicBook X 14", "X50 Pro"},
	"魅族":    {"20", "20 Infinity", "18s", "Note 20", "Lipro 智能门锁", "PANDAER 潮流手机壳", "Zero 智能手表"},
	"Redmi": {"K60 Ultra", "Note 12 Turbo", "K60", "Book Pro 15", "12C", "Note 12R", "K60 Pro"},
}

// 操作系统列表（按品牌分组）
var operatingSystems = map[string][]string{
	"小米": {"Android"},
	"华为": {"Android", "HarmonyOS"},
	"苹果": {"iOS",
		// "macOS", "watchOS",
		"iPadOS"},
	"三星":    {"Android"},
	"OPPO":  {"Android"},
	"vivo":  {"Android"},
	"一加":    {"Android"},
	"荣耀":    {"Android"},
	"魅族":    {"Android"},
	"Redmi": {"Android"},
}

// CPU型号列表（按品牌分组）
var cpus = map[string][]string{
	"小米":    {"骁龙 8 Gen 2", "天玑 9200", "骁龙 8+ Gen 1", "天玑 8200", "骁龙 7+ Gen 2", "骁龙 8 Gen 1", "天玑 8100"},
	"华为":    {"麒麟 9000S", "麒麟 9000", "骁龙 8 Gen 2", "骁龙 8+ Gen 1", "天玑 9000", "天玑 8100", "骁龙 778G+"},
	"苹果":    {"A16 Bionic", "A15 Bionic", "A14 Bionic", "M2", "M1", "S8", "A13 Bionic"},
	"三星":    {"骁龙 8 Gen 2", "Exynos 2200", "骁龙 8+ Gen 1", "Exynos 2100", "骁龙 8 Gen 1", "天玑 2200", "骁龙 7 Gen 1"},
	"OPPO":  {"骁龙 8 Gen 2", "天玑 9200", "骁龙 8+ Gen 1", "天玑 8200", "骁龙 7+ Gen 2", "天玑 8100", "骁龙 8 Gen 1"},
	"vivo":  {"骁龙 8 Gen 2", "天玑 9200", "骁龙 8+ Gen 1", "天玑 8200", "骁龙 7+ Gen 2", "天玑 9000", "骁龙 8 Gen 1"},
	"一加":    {"骁龙 8 Gen 2", "天玑 9200", "骁龙 8+ Gen 1", "天玑 8200", "骁龙 7+ Gen 2", "骁龙 8 Gen 1", "天玑 8100"},
	"荣耀":    {"骁龙 8 Gen 2", "骁龙 8+ Gen 1", "天玑 9000", "天玑 8100", "骁龙 778G+", "骁龙 7 Gen 1", "天玑 8000"},
	"魅族":    {"骁龙 8 Gen 2", "骁龙 8+ Gen 1", "天玑 9000", "骁龙 8 Gen 1", "天玑 8100", "骁龙 7 Gen 1", "天玑 8000"},
	"Redmi": {"骁龙 8 Gen 2", "天玑 9200", "骁龙 8+ Gen 1", "天玑 8200", "骁龙 7+ Gen 2", "天玑 8100", "骁龙 8 Gen 1"},
}

// 屏幕分辨率列表
var resolutions = []string{
	"3200×1440", "2716×1132", "2560×1440", "2400×1080", "2340×1080", "2280×1080", "1920×1080",
	"1600×900", "1366×768", "3840×2160", "2560×1600", "2880×1800", "3024×1964",
}

var db *gorm.DB

func main() {
	// 初始化随机数种子、数据库连接、表迁移、假数据生成（保持不变）
	rand.Seed(time.Now().UnixNano())
	dsn := "root:123456@tcp(localhost:3306)/device_db?charset=utf8mb4&parseTime=True&loc=Local"
	var err error
	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatalf("failed to connect database: %v", err)
	}
	if err := db.AutoMigrate(&DeviceInfo{}); err != nil {
		log.Fatalf("failed to migrate table: %v", err)
	}
	if err := initDataIfNeeded(); err != nil {
		log.Fatalf("failed to initialize data: %v", err)
	}

	// 路由注册（保持不变）
	r := gin.Default()
	r.GET("/api/devices", getDevices) // 分页查询接口
	// r.GET("/api/devices/:id", getDeviceByID)
	if err := r.Run(":8080"); err != nil {
		log.Fatalf("failed to start server: %v", err)
	}
}

// 初始化假数据（保持不变）
func initDataIfNeeded() error {
	var count int64
	if err := db.Model(&DeviceInfo{}).Count(&count).Error; err != nil {
		return err
	}
	if count == 0 {
		log.Println("Generating fake device data...")
		return generateFakeData(100)
	}
	log.Println("Data already exists, skipping fake data generation")
	return nil
}

// 生成假数据
func generateFakeData(count int) error {
	for i := 0; i < count; i++ {
		device := generateRandomDevice(strconv.Itoa(i + 1))
		if err := db.Create(&device).Error; err != nil {
			return err
		}
	}
	return nil
}

// 生成随机设备信息
func generateRandomDevice(id string) DeviceInfo {
	brand := brands[rand.Intn(len(brands))]
	modelList := models[brand]
	model := modelList[rand.Intn(len(modelList))]

	// 根据品牌选择合适的操作系统
	osList := operatingSystems[brand]
	os := osList[rand.Intn(len(osList))]

	// 随机生成版本号
	major := rand.Intn(15) + 5
	minor := rand.Intn(10)
	patch := rand.Intn(10)
	osVersion := fmt.Sprintf("%d.%d.%d", major, minor, patch)

	// 根据品牌选择合适的CPU
	cpuList := cpus[brand]
	cpu := cpuList[rand.Intn(len(cpuList))]

	// 随机生成其他设备信息
	ram := fmt.Sprintf("%d GB", []int{2, 4, 6, 8, 12, 16, 24, 32}[rand.Intn(8)])
	storage := fmt.Sprintf("%d GB", []int{32, 64, 128, 256, 512, 1024, 2048}[rand.Intn(7)])
	screenSize := fmt.Sprintf("%.1f 英寸", 4.0+rand.Float64()*6.0)
	resolution := resolutions[rand.Intn(len(resolutions))]
	battery := rand.Intn(101)

	return DeviceInfo{
		ID:         id,
		Brand:      brand,
		Model:      model,
		OS:         os,
		OSVersion:  osVersion,
		MACAddress: generateMACAddress(),
		CPU:        cpu,
		RAM:        ram,
		Storage:    storage,
		ScreenSize: screenSize,
		Resolution: resolution,
		Battery:    battery,
		CreatedAt:  time.Now().Add(-time.Duration(rand.Int63n(365*24)) * time.Hour).Format(time.RFC3339),
	}
}

// 生成随机MAC地址
func generateMACAddress() string {
	b := make([]byte, 6)
	rand.Read(b)
	// 设置本地管理地址位
	b[0] = (b[0] | 2) & 0xfe
	return fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x", b[0], b[1], b[2], b[3], b[4], b[5])
}

// 分页查询设备列表（核心修改）
func getDevices(c *gin.Context) {
	// 1. 获取分页参数（默认第1页，每页10条）
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))          // 页码
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10")) // 每页条数

	// 2. 校验参数（防止页码或页大小为0或负数）
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 { // 限制最大页大小为100
		pageSize = 10
	}

	// 3. 计算偏移量（offset = (page-1) * pageSize）
	offset := (page - 1) * pageSize

	// 4. 查询总条数
	var total int64
	if err := db.Model(&DeviceInfo{}).Count(&total).Error; err != nil {
		c.JSON(http.StatusInternalServerError, Response{
			Msg:  "Failed to count devices",
			Code: http.StatusInternalServerError,
			Data: nil,
		})
		return
	}

	// 5. 分页查询数据
	var devices []DeviceInfo
	if err := db.Offset(offset).Limit(pageSize).Find(&devices).Error; err != nil {
		c.JSON(http.StatusInternalServerError, Response{
			Msg:  "Failed to retrieve devices",
			Code: http.StatusInternalServerError,
			Data: nil,
		})
		return
	}

	// 6. 构造分页响应
	c.JSON(http.StatusOK, Response{
		Msg:  "Success",
		Code: http.StatusOK,
		Data: PaginationResponse{
			Total:    total,
			Page:     page,
			PageSize: pageSize,
			Data:     devices,
		},
	})
}

// 根据ID查询单设备（保持不变）
func getDeviceByID(c *gin.Context) {
	id := c.Param("id")
	var device DeviceInfo
	if err := db.First(&device, "id = ?", id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, Response{
				Msg:  "Device not found",
				Code: http.StatusNotFound,
				Data: nil,
			})
		} else {
			c.JSON(http.StatusInternalServerError, Response{
				Msg:  "Failed to retrieve device",
				Code: http.StatusInternalServerError,
				Data: nil,
			})
		}
		return
	}
	c.JSON(http.StatusOK, Response{
		Msg:  "Success",
		Code: http.StatusOK,
		Data: device,
	})
}
